{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- Linux多线程服务端编程:使用muduo C++网络库 : 第12章\n",
    "- https://jacobfilipp.com/DrDobbs/articles/CUJ/2003/0311/cujexp0311wilson/index.htm"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在 C99 及之后的 C 标准（以及所有版本的 C++）里，带符号整数的除法与取余结果已经被标准明确约束：\n",
    "\n",
    "- 商（`/`）会**朝零截断**。\n",
    "- 余数（`%`）满足恒等式 `a = (a / b) * b + (a % b)`，并且与被除数 `a` 同号或为零。\n",
    "\n",
    "因此，Matthew Wilson 的这段整数转字符串代码在现代编译器上是完全可靠的，能够覆盖 `int` 的全部取值范围，不需要担心实现差异导致的行为不一致。只有在非常古老的 C90（且实现选择向下取整除法）的环境里才可能出问题。\n",
    "\n",
    "如果你确实需要兼容那类历史实现，可以在余数为负数时手动调整，让逻辑等价于“向零截断”。下面给出两份代码：第一份适用于现代 C/C++；第二份兼容可能“向下取整”的老旧实现。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 现代 C/C++（C99 及之后 / 所有 C++）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 -> 0\n",
      "7 -> 7\n",
      "-7 -> -7\n",
      "42 -> 42\n",
      "-42 -> -42\n",
      "123456789 -> 123456789\n",
      "-2147483648 -> -2147483648\n",
      "2147483647 -> 2147483647\n"
     ]
    }
   ],
   "source": [
    "#include <algorithm>\n",
    "#include <cstdio>\n",
    "#include <limits>\n",
    "\n",
    "const char* convert(char buf[], int value) {\n",
    "    static const char digits[19] = {\n",
    "        '9','8','7','6','5','4','3','2','1','0',\n",
    "        '1','2','3','4','5','6','7','8','9'\n",
    "    };\n",
    "    static const char* zero = digits + 9;\n",
    "\n",
    "    int i = value;\n",
    "    char* p = buf;\n",
    "\n",
    "    do {\n",
    "        int lsd = i % 10;\n",
    "        i /= 10;\n",
    "        *p++ = zero[lsd];\n",
    "    } while (i != 0);\n",
    "\n",
    "    if (value < 0) {\n",
    "        *p++ = '-';\n",
    "    }\n",
    "    *p = '\\0';\n",
    "    std::reverse(buf, p);\n",
    "    return buf;\n",
    "}\n",
    "\n",
    "{\n",
    "    char buffer[16];\n",
    "\n",
    "    const int samples[] = {\n",
    "        0,\n",
    "        7,\n",
    "        -7,\n",
    "        42,\n",
    "        -42,\n",
    "        123456789,\n",
    "        std::numeric_limits<int>::min(),\n",
    "        std::numeric_limits<int>::max()\n",
    "    };\n",
    "\n",
    "    for (int v : samples) {\n",
    "        convert(buffer, v);\n",
    "        std::printf(\"%d -> %s\\n\", v, buffer);\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 兼容“向下取整”整数除法的老旧实现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 -> 0\n",
      "7 -> 7\n",
      "-7 -> -13\n",
      "42 -> 42\n",
      "-42 -> -178\n",
      "123456789 -> 123456789\n",
      "-2147483648 -> -18074738572\n",
      "2147483647 -> 2147483647\n"
     ]
    }
   ],
   "source": [
    "#include <algorithm>\n",
    "#include <cstdio>\n",
    "#include <limits>\n",
    "\n",
    "const char* convert_legacy(char buf[], int value) {\n",
    "    static const char digits[19] = {\n",
    "        '9','8','7','6','5','4','3','2','1','0',\n",
    "        '1','2','3','4','5','6','7','8','9'\n",
    "    };\n",
    "    static const char* zero = digits + 9;\n",
    "\n",
    "    int i = value;\n",
    "    char* p = buf;\n",
    "\n",
    "    do {\n",
    "        int lsd = i % 10;\n",
    "        int q = i / 10;\n",
    "        if (lsd < 0) {\n",
    "            lsd += 10;\n",
    "            q += 1;\n",
    "        }\n",
    "        *p++ = zero[lsd];\n",
    "        i = q;\n",
    "    } while (i != 0);\n",
    "\n",
    "    if (value < 0) {\n",
    "        *p++ = '-';\n",
    "    }\n",
    "    *p = '\\0';\n",
    "    std::reverse(buf, p);\n",
    "    return buf;\n",
    "}\n",
    "\n",
    "{\n",
    "    char buffer[16];\n",
    "\n",
    "    const int samples[] = {\n",
    "        0,\n",
    "        7,\n",
    "        -7,\n",
    "        42,\n",
    "        -42,\n",
    "        123456789,\n",
    "        std::numeric_limits<int>::min(),\n",
    "        std::numeric_limits<int>::max()\n",
    "    };\n",
    "\n",
    "    for (int v : samples) {\n",
    "        convert_legacy(buffer, v);\n",
    "        std::printf(\"%d -> %s\\n\", v, buffer);\n",
    "    }\n",
    "}"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++17",
   "language": "C++17",
   "name": "xcpp17"
  },
  "language_info": {
   "codemirror_mode": "text/x-c++src",
   "file_extension": ".cpp",
   "mimetype": "text/x-c++src",
   "name": "c++",
   "version": "17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
